package com.xbongbong.saas.service.toolbox.help;

import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.enums.errorcodes.StatisticsServicesErrorCodeEnum;
import org.elasticsearch.script.Script;

/**
 * es查询函数帮助类
 * @author zcp
 * @version v1.0
 * @date 2019/5/6 20:54
 * @since v1.0
 */
public class ScriptHelp {

    /**
     * 拼接es比较函数语句：两个字段的差大于value
     * @param minuend 被减数字段名
     * @param subtrahend 减数字段名
     * @param value 被比较的值，此处类型设置为String，方便传入整数或小数
     * @return org.elasticsearch.script.Script
     * @throws XbbException
     * @author zcp
     * @date 2019/5/6 22:14
     * @since v1.0
     * @version v1.0
     */
    public static Script minusFilter4Gt(String minuend, String subtrahend, String value) throws XbbException {
        /*
        （minuend的值 - subtrahend的值） > value
        如：minuend为“data.date_1”，subtrahend为“data.date_2”，value为0，
        则拼出的语句为：
        "doc['data.date_1'].value - doc['data.date_2'].value > 0"
         */
        return minusFilter(minuend, subtrahend, ConditionEnum.GREATERTHAN, value);
    }
    /**
     * 拼接es比较函数语句：两个字段的差大于等于value
     * @param minuend 被减数字段名
     * @param subtrahend 减数字段名
     * @param value 被比较的值，此处类型设置为String，方便传入整数或小数
     * @return org.elasticsearch.script.Script
     * @throws XbbException
     * @author zcp
     * @date 2019/5/6 21:25
     * @since v1.0
     * @version v1.0
     */
    public static Script minusFilter4Egt(String minuend, String subtrahend, String value) throws XbbException {
        /*
        （minuend的值 - subtrahend的值） >= value
        如：minuend为“data.date_1”，subtrahend为“data.date_2”，value为0，
        则拼出的语句为：
        "doc['data.date_1'].value - doc['data.date_2'].value >= 0"
         */
        return minusFilter(minuend, subtrahend, ConditionEnum.GREATEREQUAL, value);
    }

    /**
     * 拼接es比较函数语句：两个字段的差大于等于value
     * @param minuend 被减数字段名
     * @param subtrahend 减数字段名
     * @param value 被比较的值，此处类型设置为String，方便传入整数或小数
     * @return org.elasticsearch.script.Script
     * @throws XbbException
     * @author zcp
     * @date 2019/5/6 21:27
     * @since v1.0
     * @version v1.0
     */
    public static Script minusFilter4Lt(String minuend, String subtrahend, String value) throws XbbException {
        /*
        （minuend的值 - subtrahend的值） < value
        如：minuend为“data.date_1”，subtrahend为“data.date_2”，value为0，
        则拼出的语句为：
        "doc['data.date_1'].value - doc['data.date_2'].value < 0"
         */
        return minusFilter(minuend, subtrahend, ConditionEnum.LESSTHAN, value);
    }
    /**
     * 拼接es比较函数语句：两个字段的差小于等于value
     * @param minuend 被减数字段名
     * @param subtrahend 减数字段名
     * @param value 被比较的值，此处类型设置为String，方便传入整数或小数
     * @return org.elasticsearch.script.Script
     * @throws XbbException
     * @author zcp
     * @date 2019/5/6 22:17
     * @since v1.0
     * @version v1.0
     */
    public static Script minusFilter4Elt(String minuend, String subtrahend, String value) throws XbbException {
        /*
        （minuend的值 - subtrahend的值） <= value
        如：minuend为“data.date_1”，subtrahend为“data.date_2”，value为0，
        则拼出的语句为：
        "doc['data.date_1'].value - doc['data.date_2'].value <= 0"
         */
        return minusFilter(minuend, subtrahend, ConditionEnum.LESSEQUAL, value);
    }

    /**
     * 拼接es比较函数语句：两个字段的差与value的比较
     * @param minuend 被减数字段名
     * @param subtrahend 减数字段名
     * @param conditionEnum 比较枚举
     * @param value 被比较的值，数字型字符串，必须为整数或小数
     * @return org.elasticsearch.script.Script
     * @throws XbbException
     * @author zcp
     * @date 2019/5/6 21:18
     * @since v1.0
     * @version v1.0
     */
    public static Script minusFilter(String minuend, String subtrahend, ConditionEnum conditionEnum, String value) throws XbbException {
        if (StringUtil.isEmpty(minuend) || StringUtil.isEmpty(subtrahend) || conditionEnum == null || StringUtil.isEmpty(value)) {
            throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224022, String.format(StatisticsServicesErrorCodeEnum.API_ERROR_224022.getMsg(), "es函数语句生成错误"));
        }
        if (!StringUtil.isDigital(value)) {
            throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224022, String.format(StatisticsServicesErrorCodeEnum.API_ERROR_224022.getMsg(), "被比较的值需为数字型字符串"));
        }

        StringBuilder str = new StringBuilder();
        /*
        如：minuend为“data.date_1”，subtrahend为“data.date_2”，conditionEnum为GREATEREQUAL（>=），value为0，
        则拼出的语句为：
        "doc['data.date_1'].value - doc['data.date_2'].value >= 0"
         */
        if (minuend.contains("date") || minuend.toLowerCase().contains("time")) {
            str.append("doc['").append(minuend).append("'].value.toEpochSecond() - doc['").append(subtrahend).append("'].value.toEpochSecond() ").append(conditionEnum.getReplaceSymbol()).append(" ").append(value);
        } else {
            str.append("doc['").append(minuend).append("'].value - doc['").append(subtrahend).append("'].value ").append(conditionEnum.getReplaceSymbol()).append(" ").append(value);

        }
        Script script = new Script(str.toString());
        return script;
    }

    /**
     * 得到两个字段相乘的Script
     * @param x 乘数字段名
     * @param y 乘数字段名
     * @return org.elasticsearch.script.Script
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public static Script scriptMultiply(String x, String y) {
        if (StringUtil.isEmpty(x) || StringUtil.isEmpty(y)) {
            return null;
        }
        StringBuilder str = new StringBuilder();
        str.append("doc['").append(x).append("'].value * doc['").append(y).append("'].value ");
        return new Script(str.toString());
    }
}
